#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;

[InitializeOnLoad]
public class ModiParentOnly
{
    public static ModiParentOnly _ins;

    //按住哪个键生效
    private static EventModifiers Key = EventModifiers.Shift;
    private bool _prevHeld;
    private bool _currentHeld;

    static ModiParentOnly()
    {
        _ins = new ModiParentOnly();
    }
    private ModiParentOnly()
    {
        SceneView.duringSceneGui += KeyHeld;
    }
    ~ModiParentOnly()
    {
        StopTracking();
        SceneView.duringSceneGui -= KeyHeld;
    }
    private void KeyHeld(SceneView view)
    {
        if (Event.current != null)
        {
            _currentHeld = (Event.current.modifiers & Key) != 0;
            if (_currentHeld != _prevHeld)
            {
                if (_currentHeld)
                {
                    StartTracking();
                }
                else
                {
                    StopTracking();
                }
            }
            _prevHeld = _currentHeld;
        }
    }

    private struct TransformValueInfo
    {
        public Vector3 position;
        public Quaternion rotation;
        public TransformValueInfo(Transform transform)
        {
            position = transform.position;
            rotation = transform.rotation;
        }
        public void Get(Transform transform)
        {
            position = transform.position;
            rotation = transform.rotation;
        }
        public bool IsSameTo(Transform transform)
        {
            return position == transform.position &&
                rotation == transform.rotation;
        }
        public void ApplyTo(Transform transform)
        {
            transform.SetPositionAndRotation(position, rotation);
        }
    }

    private class ParentInfo
    {
        public Transform target;
        public TransformValueInfo last;
        public TransformValueInfo[] children;

        public ParentInfo(Transform parent)
        {
            target = parent;
            last = new TransformValueInfo(parent);
            children = new TransformValueInfo[parent.childCount];
            for (int i = 0; i < parent.childCount; i++)
            {
                var trans = parent.GetChild(i).transform;
                children[i] = new TransformValueInfo(trans);
            }
        }
    }
    private ParentInfo[] _infos;

    public void ModiOnly(Transform parent,System.Action<Transform> modi)
    {
        var info = new ParentInfo(parent);
        modi?.Invoke(parent);
        RestoreChildren(info);
    }

    private void StartTracking()
    {
        var selections = Selection.gameObjects;
        _infos = new ParentInfo[selections.Length];
        for (int i = 0; i < _infos.Length; i++)
        {
            _infos[i] = new ParentInfo(selections[i].transform);
        }
        SceneView.duringSceneGui += Tracking;
    }
    private void StopTracking()
    {
        _infos = null;
        SceneView.duringSceneGui -= Tracking;
    }
    private void Tracking(SceneView view)
    {
        if (_infos == null) return;
        // 检测父物体变化
        for (int i = 0; i < _infos.Length; i++)
        {
            var info = _infos[i];
            DrawAxes(info.target,view.camera);
            if (!info.last.IsSameTo(info.target))
            {
                RestoreChildren(info);
                info.last.Get(info.target);
            }
        }
    }
    private void DrawAxes(Transform target,Camera camera)
    {
        if (!target) return;
        if (Selection.activeTransform == target) return;
        // 绘制模式判断
        if (Tools.current != Tool.Move) return;

        Camera cam = camera;
        Vector3 origin = target.position;

        // 计算基于摄像机距离的尺寸
        float distance = Vector3.Distance(cam.transform.position, origin);
        float baseScale = distance / 5f;
        float axisLength = 0.6f * baseScale;
        float arrowSize = 0.1f * baseScale;
        float lineThickness = 1.7f; 

        // 获取方向向量
        bool isGlobal = Tools.pivotRotation == PivotRotation.Global;
        Vector3 right = isGlobal ? Vector3.right : target.right;
        Vector3 up = isGlobal ? Vector3.up : target.up;
        Vector3 forward = isGlobal ? Vector3.forward : target.forward;

        // 带抗锯齿的线段绘制
        Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;

        // X轴
        using (new Handles.DrawingScope(Color.red))
        {
            Handles.DrawLine(origin, origin + right * axisLength, lineThickness);
            DrawArrow(origin + right * axisLength, right, arrowSize);
        }

        // Y轴
        using (new Handles.DrawingScope(Color.green))
        {
            Handles.DrawLine(origin, origin + up * axisLength, lineThickness);
            DrawArrow(origin + up * axisLength, up, arrowSize);
        }

        // Z轴
        using (new Handles.DrawingScope(Color.blue))
        {
            Handles.DrawLine(origin, origin + forward * axisLength, lineThickness);
            DrawArrow(origin + forward * axisLength, forward, arrowSize);
        }
    }
    private static void DrawArrow(Vector3 tipPos, Vector3 direction, float size)
    {
        float visibleSize = size * 1f;
        Handles.ConeHandleCap(0,tipPos - 0.3f * visibleSize * direction,Quaternion.LookRotation(direction),visibleSize,EventType.Repaint);
    }
    private void RestoreChildren(ParentInfo info)
    {
        if (info.children.Length == 0) return;
        for (int i = 0; i < info.children.Length; i++)
        {
            var child =info.target.GetChild(i);
            Undo.RecordObject(child,"RestoreChild");
            info.children[i].ApplyTo(child);
        }
    }

    [MenuItem("Tools/移动到子物体位置中心")]
    public static void ToCenter()
    {
        _ins.ModiOnly(Selection.activeTransform, t => t.position = Vector3.zero);
        var parents = Selection.gameObjects;
        foreach(var p in parents)
        {
            var trans = p.transform;
            Vector3 sum = Vector3.zero;
            for (int i = 0; i < trans.childCount; i++)
            {
                sum += trans.GetChild(i).position;
            }
            _ins.ModiOnly(trans, t => t.position = sum / trans.childCount);
        }
    }
}
#endif